package unv.esiag.uchiha.publishers;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.Vector;

import unv.esiag.uchiha.semaphore.Semaphore;
import unv.esiag.uchiha.subscribers.Subscriber;

public class Publisher {
	private static Vector<Publisher> publishers;
	private static final int MAXLEN = 5;
	private Vector<Subscriber> remotes;
	private Semaphore publish;
	private int counter;
	private Publisher() {
		this.remotes = new Vector<Subscriber>();
		this.publish = new Semaphore();
		this.counter = 0;
	}
	public boolean addRemoteSubscriber(Subscriber subscriber){
		this.publish.stop();
		for(int i = 0;i<this.remotes.size();i++){
			if(this.remotes.get(i).toString().equals(subscriber.toString())){
				this.publish.signal();
				return false;
			}
		}
		this.remotes.add(subscriber);
		this.publish.signal();
		return true;
	}
	public void setCounter(int counter) {
		this.counter = counter;
	}
	public int getCounter() {
		return counter;
	}
	public void publishe(Serializable serializable) throws RemoteException{
		this.publish.stop();
		Subscriber[] subs = new Subscriber[this.remotes.size()];
		this.remotes.copyInto(subs);
		this.remotes.clear();
		for(int i = 0;i<subs.length;i++){
			boolean error = false;
			try{
				subs[i].publish(serializable);
			}catch(RemoteException e){
				error = true;
				throw new RemoteException("Connexion Interompu");
			}
			if(!error){
				this.remotes.add(subs[i]);
			}
		}
		this.publish.signal();
	}
	public static Publisher getPublisher(){
		Publisher pub;
		if(publishers == null){
			publishers = new Vector<Publisher>();
			pub = new Publisher();
			publishers.add(pub);
		}else{
			pub = publishers.get(publishers.size() - 1);
			if(pub.getCounter() == MAXLEN){
				pub = new Publisher();
				publishers.add(pub);
			}
		}
		pub.setCounter(pub.getCounter() + 1);
		return pub;
	}
}
